package sweezy.swf.tools.flex
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TextEvent;
	import flash.net.FileReference;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.utils.ByteArray;
	
	import mx.controls.Alert;
	import mx.core.Container;
	import mx.core.LayoutContainer;
	import mx.events.ListEvent;
	
	import sweezy.swf.ISWFElement;
	import sweezy.swf.SWF;
	import sweezy.swf.decoder.SWFDecoder;
	import sweezy.swf.structure.ABCData;
	import sweezy.swf.tools.abcdump.ABCDump;
	import sweezy.swf.tools.abcdump.ArrayStream;
	import sweezy.swf.tools.abcdump.StringDumpStream;
	import sweezy.swf.tools.abcdump.IDumpStream;

	public class InspectorView extends LayoutContainer
	{

		private var _name:String;

		private var _swf:SWF;

		private var _swfNode:SWFNode;

		private var _view:Inspector;

		public function InspectorView()
		{
			_view = Inspector(this);
		}

		override protected function createChildren():void
		{
			super.createChildren();

			_view.tree.addEventListener(ListEvent.ITEM_CLICK, treeItemClickHandler);
			_view.property.addEventListener(ListEvent.ITEM_CLICK, propertyItemClickHandler);
			_view.loadButton.addEventListener(MouseEvent.CLICK, loadButtonClickHandler);
			_view.saveButton.addEventListener(MouseEvent.CLICK, saveButtonClickHandler);
			_view.clearButton.addEventListener(MouseEvent.CLICK, clearButtonClickHandler);
			_view.copyright.addEventListener(TextEvent.LINK, copyrightClickHandler);

			clear(null);
		}

		private function clear(swf:SWF):void
		{
			_swf = swf;
			_swfNode = swf === null ? null : new SWFNode(swf, "swf", SWF, false, null);
			_view.tree.dataProvider = _swfNode;
			_view.property.dataProvider = null;
			_view.binary.dataProvider = null;

			_view.fileName.text = swf === null ? null : _name;
			_view.saveButton.enabled = swf !== null;
			_view.clearButton.enabled = swf !== null;
		}

		private function clearButtonClickHandler(e:MouseEvent):void
		{
			clear(null);
		}

		private function copyrightClickHandler(e:TextEvent):void
		{
			navigateToURL(new URLRequest("http://code.google.com/p/sweezy/"));
		}

		private function dumpABC(value:ISWFElement):void
		{
			var stream:ArrayStream;
			if (value !== null)
			{
				if (value is ABCData)
				{
					stream = new ArrayStream();
					ABCDump.dumpABCData(value as ABCData, stream);
					_view.tab.selectedChild = _view.abcdump.parent as Container;
				}
			}

			_view.abcdump.dataProvider = stream === null ? "" : stream.list;
		}

		private function loadButtonClickHandler(e:MouseEvent):void
		{
			var file:FileReference = new FileReference();
			var browseHandler:Function = function(e:Event):void
			{
				file.removeEventListener(Event.CANCEL, browseHandler);
				file.removeEventListener(Event.SELECT, browseHandler);

				if (e.type !== Event.SELECT)
				{
					return;
				}

				var loadHandler:Function = function(e:Event):void
				{
					file.removeEventListener(Event.COMPLETE, loadHandler);
					file.removeEventListener(IOErrorEvent.IO_ERROR, loadHandler);
					file.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loadHandler);

					if (e.type === Event.COMPLETE)
					{
						setSWF(file.data);
					}
				};

				_name = file.name;
				file.addEventListener(Event.COMPLETE, loadHandler);
				file.addEventListener(IOErrorEvent.IO_ERROR, loadHandler);
				file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loadHandler);
				file.load();
			};

			file.addEventListener(Event.CANCEL, browseHandler);
			file.addEventListener(Event.SELECT, browseHandler);
			file.browse();
		}

		private function processNode(e:SWFNode):void
		{
			dumpABC(e.value as ISWFElement);
		}

		private function propertyItemClickHandler(e:ListEvent):void
		{
			var p:PropertyItem = e.itemRenderer.data as PropertyItem;
			if (p.data is ByteArray)
			{
				_view.tab.selectedChild = _view.binary.parent as Container;
				_view.binary.dataProvider = p.data;
			}
			else
			{
				_view.binary.dataProvider = null;
			}
		}

		private function saveButtonClickHandler(e:MouseEvent):void
		{
			_swfNode.encode();

			var bytes:ByteArray = _swf.encode();
			var file:FileReference = new FileReference();
			file.save(bytes, _name);
		}

		private function setSWF(bytes:ByteArray):void
		{
			var decoder:SWFDecoder = new SWFDecoder();
			var swf:SWF = decoder.decode(bytes);

			if (!decoder.hasErrors)
			{
				clear(swf);
			}
			else
			{
				Alert.show(decoder.errors.join("\n"), "An error occurred");
			}
		}

		private function treeItemClickHandler(e:ListEvent):void
		{
			_view.binary.dataProvider = null;
			_view.property.dataProvider = e.itemRenderer.data;

			if (e.itemRenderer.data is SWFNode)
			{
				processNode(e.itemRenderer.data as SWFNode);
			}
		}
	}
}
